home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / tool / artemis1 / src / mask.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-11  |  4.4 KB  |  218 lines

  1. /*
  2.     mask.c:マスク管理
  3.  
  4.     mask_init            領域指定処理の初期化
  5.     mask_chkxy            ある座標が、指定領域内かどうかを調べる
  6.     mask_chkxylen        ある座標から右に何ドット同じフラグが連続しているか
  7.     mask_clear
  8.     mask_hline            set, clear, exchange の3方式でのマスクの描画
  9.     mask_setswitch        マスクの有効/無効化スイッチ
  10.     mask_tempoff_begin
  11.     mask_tempoff_end
  12. */
  13.  
  14. #include <stdio.h>
  15. #include <stdefs.h>
  16. #include <egb.h>
  17. #include <malloc.h>
  18. #include <stdlib.h>
  19. #include <msdos.cf>
  20. #include <memory.h>
  21. #include <interrup.cf>
  22.  
  23. #include "ge.h"
  24. #include "plt16.h"
  25. #include "math2.h"
  26. #include "decimal.h"
  27. #include "dispman.h"
  28. #include "imageman.h"
  29.  
  30.  
  31. static char        *mask_buf = NULL, *mask_buf2 = NULL;
  32. static bool        masksizevar = NO;    // マスクバッファの縦横サイズが可変か
  33. static int        maskxlen, maskylen;    // masksizevar=YES 時の縦横サイズ
  34. static    bool    mask_sw;            // マスクが有効かどうか
  35.  
  36.  
  37. #define    MASKXLEN    512
  38.  
  39. int mask_init(void)
  40. // 返値: 0=成功  0以外=メモリ不足
  41. {
  42.     int size;
  43.     if (EIMgetxsize() <= MASKXLEN)
  44.         masksizevar = NO, maskxlen = MASKXLEN;
  45.     else
  46.         masksizevar = YES, maskxlen=(EIMgetxsize()+7)&0xffff8;
  47.     maskylen = EIMgetysize();
  48.     size = (maskxlen / 8) * maskylen;
  49.     if (mask_buf == NULL)
  50.     {
  51.         if ((mask_buf = calloc(1,size*2)) == NULL)
  52.         {
  53.             DEBUG_MSG("マスクバッファ用メモリ領域 確保失敗");
  54.             return -1;
  55.         }
  56.         else
  57.             DEBUG_MSG("マスクバッファ用メモリ領域 確保成功");
  58.         mask_buf2 = mask_buf + size;
  59.     }
  60.     mask_sw = YES;
  61.     return 0;
  62. }
  63.  
  64.  
  65. void mask_clear(void)
  66. {
  67.     memset(mask_buf, 0, (maskxlen >> 3)*maskylen);
  68. }
  69.  
  70.  
  71. void mask_hline(int x1,int x2,int y, int method)
  72. {
  73.     #define SETMASK(p, bitpat, method) \
  74.         ( (method)==2 ? *(p) ^= (bitpat)  : \
  75.           (method)==1 ? *(p) &= ~(bitpat) : \
  76.                         *(p) |= (bitpat) )
  77.     char *p;  int x,leftx,rightx,xr1,xr2;
  78.     if (x1 > x2)
  79.         swap(x1,x2);
  80.     p = mask_buf + (maskxlen >> 3) * y + (x1 >> 3);
  81.     leftx = x1 & 0xfff8;
  82.     xr1 = x1 & 7;
  83.     rightx = x2 & 0xfff8;
  84.     xr2 = x2 & 7;
  85.     if (leftx == rightx)
  86.     {
  87.         SETMASK(p, (0xff << xr1) & (0xff >> (7-xr2)), method);
  88.     }
  89.     else
  90.     {
  91.         x = leftx;
  92.         SETMASK(p,(0xff<<xr1)&0xff,method), p++, x += 8;    // 左端
  93.         while (x < rightx)                                    // 真ん中
  94.             SETMASK(p,0xff,method), p++, x += 8;
  95.         SETMASK(p, (0xff >> (7-xr2)), method);                // 右端
  96.     }
  97. }
  98.  
  99.  
  100.  
  101. static char bit8[] = {1,2,4,8,16,32,64,128};
  102.  
  103.  
  104. static bool _mask_chkxy(char *maskbuf, int x, int y)
  105. // (x,y) が領域指定されているかを調べる
  106. {
  107.     if (!mask_sw || x < 0 || y < 0 || maskxlen <= x || maskylen <= y)
  108.         return NO;
  109.     if (!masksizevar)
  110.     {
  111.         char r = (x & 7);
  112.         return (*(maskbuf+y*(MASKXLEN/8)+(x>>3)) & bit8[r]) == 0 ? NO : YES;
  113.     }
  114.     else
  115.     {
  116.         char r = (x & 7);
  117.         return (*(maskbuf+y*(maskxlen>>3)+(x>>3)) & bit8[r]) == 0 ? NO : YES;
  118.     }
  119. }
  120.  
  121. bool mask_chkxy(int x, int y)
  122. {
  123.     return _mask_chkxy(mask_buf, x, y);
  124. }
  125.  
  126. bool mask_chkxy_back(int x, int y)
  127. {
  128.     return _mask_chkxy(mask_buf2, x, y);
  129. }
  130.  
  131.  
  132. static int _mask_chkxylen(int x,int xmax,int y,bool nega, char *maskbuf)
  133. // (x,y) から右に何ドット連続して指定されているかを調べる(or 0)
  134. // nega: 働きを逆にする(領域指定されていない点の連続数を求める)
  135. {
  136.     int _maxx = _min(xmax,maskxlen-1);
  137.     int xbytes = maskxlen >> 3;
  138.     char *p = maskbuf + y*xbytes + (x>>3);
  139.     int i,r;
  140.     if (!nega)
  141.     {
  142.         if (!mask_sw || x < 0 || _maxx < x || y < 0 || maskylen <= y)
  143.             return 0;
  144.         for (i=x,r=x&7; i<=_maxx; )
  145.         {
  146.             if (r==0 && *p == 255)
  147.             {
  148.                 i+=8, p++;
  149.                 continue;
  150.             }
  151.             else if ((*p & bit8[r]) == 0)
  152.                 break;
  153.             i++;
  154.             if (++r == 8)
  155.                 r=0, p++;
  156.         }
  157.     }
  158.     else
  159.     {
  160.         int dr = _max(0, xmax - x + 1);
  161.         if (!mask_sw || x < 0 || _maxx < x || y < 0 || maskylen <= y)
  162.             return dr;
  163.         for (i=x,r=x&7; i<=_maxx; )
  164.         {
  165.             if (r==0 && *p == 0)
  166.             {
  167.                 i+=8, p++;
  168.                 continue;
  169.             }
  170.             else if ((*p & bit8[r]) != 0)
  171.                 break;
  172.             i++;
  173.             if (++r == 8)
  174.                 r=0, p++;
  175.         }
  176.     }
  177.     i = _min(_maxx+1,i);
  178.     return i-x;
  179. }
  180.  
  181. int mask_chkxylen(int x,int xmax,int y,bool nega)
  182. {
  183.     return _mask_chkxylen(x,xmax,y,nega, mask_buf);
  184. }
  185.  
  186. int mask_chkxylen_back(int x,int xmax,int y,bool nega)
  187. {
  188.     return _mask_chkxylen(x,xmax,y,nega, mask_buf2);
  189. }
  190.  
  191. bool mask_getswitch(void)
  192. {
  193.     return mask_sw;
  194. }
  195.  
  196. void mask_setswitch(bool sw)
  197. {
  198.     mask_sw = sw;
  199. }
  200.  
  201. void    mask_backup(void)
  202. {
  203.     memcpy(mask_buf2, mask_buf, (maskxlen >> 3)*maskylen);
  204. }
  205.  
  206. static bool tempmasksw;
  207.  
  208. void    mask_tempoff_begin(void)
  209. {
  210.     tempmasksw = mask_sw;
  211.     mask_sw = NO;
  212. }
  213.  
  214. void    mask_tempoff_end(void)
  215. {
  216.     mask_sw = tempmasksw;
  217. }
  218.